package mini.hug;

import java.awt.event.KeyEvent;
import java.util.ArrayList;

import audio.Audio;
import audio.Clip;
import bogus.userInput.Input;
import owg.util.Calc;
import owg.util.euclidian.Compass;
import owg.util.opengl.ColorF;
import world.Sound;
import hubol.Entity;
import hubol.Sprite;

public class Bogus extends Entity{
	private final static Sprite HUG = new Sprite("hug"), PUNISH = new Sprite("scorch");
	private final Shake s = Hug.me.shake();
	private double image;
	private float in = 0;
	
	private int lastWalk = 0;
	public final Clip step = Audio.getClip("steploop");
	private double walkimg;
	
	public int hug = 0;
	public boolean ACTUALLYHUGGING = false, DEAD = false, PUNISHED = false, HONESTLY = false, FCK = false;
	
	public double addX = 0;
	
	private ArrayList<Heart> hearts = new ArrayList<Heart>();
	
	private double transform = 100, gain = .5;
	private final double initialTransform = transform;

	public Bogus(double x, double y) {
		this(x, y, 3);
		Sound.playPitched("bogus");
	}
	
	public Bogus(double x, double y, int alarm){
		super(x, y, alarm);
		sprite = new Sprite("bogus");
		sprite.setOrigin(Compass.SOUTH);
		HUG.setOrigin(Compass.SOUTH);
		PUNISH.setOrigin(Compass.SOUTH);
		image = 0;
		alarmEvent(0);
		
		setDepth(600 - (int)y);
	}
	
	public void alarmEvent(int i){
		if (i == 0){
			imageSingle = (float)Calc.random(2);
			imageSpeed = (float)Calc.rangedRandom(.125);
			alarm[0] = 1 + (int)Calc.random(20);
		}
		else if (i == 1){
			gain = Math.max(0, gain - .05);
			Hug.me.gain(gain);
			Sound.playPitched("quiver", .25);
			addX *= -1;
			alarm[1] = 3;
		}
		else if (i == 2){
			Sound.playPitched("birgus", .001);
			for (int j=0; j<8; j++)
				new Exhaust(x, y, j * 45, 5);
			//TODO soudn????
			new Understanding(xscale);
			HONESTLY = true;
		}
	}
	
	public void heart(){
		Sound.playPitched("bg1");
		Hug.me.SCORE++;
		hearts.add(new Heart(x + 47, y, Hug.me.SCORE));
	}
	
	public void destroy(){
		hearts.clear();
		super.destroy();
	}
	
	public void step(){
		if (!HONESTLY){
			in = (float)Calc.approach(in, 1, 4);
			int up = 0, walk = 0;
			if (!ACTUALLYHUGGING && !DEAD && !FCK){
				if (Input.checkKey(KeyEvent.VK_LEFT)){
					xscale = -1;
					hspeed = Math.max(-4, hspeed - .5);
					walk = 1;
				}
				else if (Input.checkKey(KeyEvent.VK_RIGHT)){
					xscale = 1;
					hspeed = Math.min(4, hspeed + .5);
					walk = 1;
				}
				else
					hspeed = Calc.approach(hspeed, 0, 2);
				
				if (Input.checkKey(KeyEvent.VK_UP)){
					vspeed = Math.max(-4, vspeed - .5);
					up = 1;
					walk = 1;
				}
				else if (Input.checkKey(KeyEvent.VK_DOWN)){
					vspeed = Math.min(4, vspeed + .5);
					walk = 1;
				}
				else
					vspeed = Calc.approach(vspeed, 0, 2);
			}
			else{
				hspeed = Calc.approach(hspeed, 0, 2);
				vspeed = Calc.approach(vspeed, 0, 2);
			}
			
			if (walk == 1 && lastWalk == 0)
				step.loop();
			else if (walk == 0 && lastWalk == 1)
				step.stop();
			lastWalk = walk;
			
			//math!
			if (getSpeed() > 3)
				setSpeed(3);
			
			final double spd = getSpeed();
			if (Hug.me.SCORE == 3 && spd > 0 && !FCK){
				step.stop();
				transform = Math.max(0, transform - spd);
				Hug.me.pitch(2 - (transform / initialTransform));
				Hug.me.gain(.5 + (.5 * (transform / initialTransform)));
				
				if (transform == 0){
					for (Heart h : hearts)
						h.kill();
					hearts.clear();
					addX = 1;
					alarm[1] = 3;
					alarm[2] = 120;
					FCK = true;
				}
			}
			
			//movin!
			x += hspeed;
			y += vspeed;
			
			//loopin!
			Hug.me.rememberDistance();
			for (Heart h : hearts)
				h.rememberDistance();
			
			double a = x, b = y;
			if (x > 1728)
				x -= 2592;
			else if (x < -864)
				x += 2592;
			
			if (y > 972)
				y -= 1458;
			else if (y < -486)
				y += 1458;
			
			if (a != x || b != y){
				Hug.me.forceUpdate();
				for (Heart h : hearts)
					h.forceUpdate();
			}
			
			imageSingle += imageSpeed;
			
			if (walk == 0){
				image = Math.abs(imageSingle) % 2.0;
				walkimg = 0;
			}
			else{
				image = walkimg % 2.0;
				walkimg += .1;
			}
			image += (up * 8) + (walk * 2);
			
			setDepth(600 - (int)y);
			
			hug = 0;
		}
		else
			destroy();
		
		alarmStep();
	}
	
	public void render(){
		if (!HONESTLY){
			if (PUNISHED)
				PUNISH.render(Math.abs(imageSingle) % 2.0, x + s.x, y + s.y, Hug.SIZE, Hug.SIZE, (float)(s.z / 12.0), ColorF.WHITE);
			else if (!ACTUALLYHUGGING)
				sprite.render(image + (hug * 4), x + s.x + addX, y + s.y, xscale * Hug.SIZE * in, Hug.SIZE * in, (float)(s.z / 10.0), ColorF.WHITE);
			else
				HUG.render(0, x + s.x, y + s.y, Hug.SIZE, Hug.SIZE, (float)(s.z / 12.0), ColorF.WHITE);
		}
	}

}
